package com.tuanzi.loan.business.service.collaborate.impl;

import com.google.common.collect.Lists;
import com.tuanzi.loan.business.entity.CurrentUser;
import com.tuanzi.loan.business.entity.LoginUser;
import com.tuanzi.loan.business.entity.collaborate.NewCollaborateChannelRatio;
import com.tuanzi.loan.business.entity.collaborate.NewCollaborateChannelUser;
import com.tuanzi.loan.business.entity.collaborate.StatCollaborateCheckIn;
import com.tuanzi.loan.business.repository.collaborate.CollaborateChannelRatioRepository;
import com.tuanzi.loan.business.repository.collaborate.CollaborateChannelUserRepository;
import com.tuanzi.loan.business.repository.collaborate.StatCollaborateCheckInLoginRepository;
import com.tuanzi.loan.business.repository.statistics.custom.StatCheckInCustomRepository;
import com.tuanzi.loan.business.service.collaborate.StatCollaborateCheckInLoginService;
import com.tuanzi.loan.core.aspect.Debug;
import com.tuanzi.loan.core.service.CommonServiceImpl;
import com.tuanzi.loan.core.vo.PageSearcher;
import com.tuanzi.loan.vo.request.statistics.login.StatCheckInRequest;
import com.tuanzi.server.loan_base.util.DateUtils;
import org.apache.commons.beanutils.BeanUtilsBean2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.retry.RetryException;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * User: liangZongXi
 * Create time: 15:21 2019/5/10
 * Description:
 */

@Debug
@Service
@Transactional
@Retryable(value = { RetryException.class })
public class StatCollaborateCheckInLoginServiceImpl extends CommonServiceImpl<StatCollaborateCheckIn, Long> implements StatCollaborateCheckInLoginService{

    private final CollaborateChannelUserRepository collaborateChannelUserRepository;
    private final CollaborateChannelRatioRepository collaborateChannelRatioRepository;
    private final StatCollaborateCheckInLoginRepository statCollaborateCheckInLoginRepository;
    private final StatCheckInCustomRepository statCheckInCustomRepository;

    @Autowired
    public StatCollaborateCheckInLoginServiceImpl(CollaborateChannelUserRepository collaborateChannelUserRepository, CollaborateChannelRatioRepository collaborateChannelRatioRepository, StatCollaborateCheckInLoginRepository statCollaborateCheckInLoginRepository, StatCheckInCustomRepository statCheckInCustomRepository) {
        this.collaborateChannelUserRepository = collaborateChannelUserRepository;
        this.collaborateChannelRatioRepository = collaborateChannelRatioRepository;
        this.statCollaborateCheckInLoginRepository = statCollaborateCheckInLoginRepository;
        this.statCheckInCustomRepository = statCheckInCustomRepository;
    }

    @Override
    public void statKlCheckInInfo(List<NewCollaborateChannelRatio> allChannelRatio, Date date) {
        if(null == allChannelRatio || allChannelRatio.size() == 0 || null == date){
            return;
        }

        List<Integer> channelList = allChannelRatio.parallelStream().map(NewCollaborateChannelRatio::getChannelId).collect(Collectors.toList());

        List<StatCollaborateCheckIn> allCheckInfo = statCheckInCustomRepository.findAllByCreateDateAndChannelIn(channelList, date);
        for (NewCollaborateChannelRatio channelInfo : allChannelRatio) {
            for (StatCollaborateCheckIn checkInfo : allCheckInfo) {
                if(checkInfo.getChannelCode().equals(channelInfo.getChannelId().toString())){
                    klOperation(checkInfo, channelInfo.getRatio());
                    checkInfo.setId(null);
                }
            }
        }

        statCollaborateCheckInLoginRepository.save(allCheckInfo);

    }

    @Override
    public Page<StatCollaborateCheckIn> list(PageSearcher<StatCheckInRequest> pageSearcher) {
        LoginUser loginUser = CurrentUser.get();
        if(null == loginUser){
            return new PageImpl<>(Lists.newArrayList());
        }

        String account = loginUser.getAccount();
        if(StringUtils.isBlank(account)){
            return new PageImpl<>(Lists.newArrayList());
        }
        //查询用户关联哪个渠道
        List<NewCollaborateChannelUser> channelUsers = collaborateChannelUserRepository.findByUserName(account);
        if(Objects.isNull(channelUsers) || channelUsers.size() <= 0){
            return new PageImpl<>(Lists.newArrayList());
        }

        List<Integer> channelList = channelUsers.stream().map(NewCollaborateChannelUser::getChannelId).collect(Collectors.toList());
        Page<StatCollaborateCheckIn> list = statCollaborateCheckInLoginRepository.list(pageSearcher.getSearchCondition(),
                pageSearcher.getPageable(), channelList);

        List<NewCollaborateChannelRatio> channelRatios = collaborateChannelRatioRepository.findByChannelIdIn(channelList);

        setKlDataAndNotShowCol(list, channelRatios);

        return list;
    }

    private void setKlDataAndNotShowCol(Page<StatCollaborateCheckIn> list, List<NewCollaborateChannelRatio> channelRatios) {
        long todayTimestamp = Timestamp.valueOf(DateUtils.getCurrentDate() +" 00:00:00").getTime();
        for (NewCollaborateChannelRatio channelRatio : channelRatios) {
            Integer ratio = channelRatio.getRatio();
            String checkShow = channelRatio.getCheckShow();
            Integer channelId = channelRatio.getChannelId();
            for (StatCollaborateCheckIn response : list ) {
                if(response.getChannelCode().equals(channelId.toString())){
                    //当天的，进行扣量
                    if(response.getCreateDate().getTime() == todayTimestamp){
                        klOperation(response, ratio);
                    }

                    //置空非展示字段
                    setNullByChannelAndShowType(response, StringUtils.isBlank(checkShow) ? null : checkShow.split(","));
                }
            }
        }
    }

    private void setNullByChannelAndShowType(StatCollaborateCheckIn response, String[] typeCols) {
        if(null == typeCols || null == response){
            return;
        }

        // 临时保存需要保留下来的数据，全部置空，后重新设置
        StatCollaborateCheckIn tempCheckIn = new StatCollaborateCheckIn();
        tempCheckIn.setId(response.getId());
        tempCheckIn.setCreateDate(response.getCreateDate());
        tempCheckIn.setPlatform(response.getPlatform());
        tempCheckIn.setChannelCode(response.getChannelCode());
        tempCheckIn.setActivityId(response.getActivityId());
        tempCheckIn.setProductId(response.getProductId());

        for (String col : typeCols) {
            if("17".equals(col)){//以下数字请看数据字典 key COLLABORATE_CHECK_SHOW_TYPE 或者 CollaborateColShowEnum 的id
                tempCheckIn.setH5ViewPageCount(response.getH5ViewPageCount());
                continue;
            }
            if("18".equals(col)){
                tempCheckIn.setH5CheckInCount(response.getH5CheckInCount());
                continue;
            }
            if("19".equals(col)){
                tempCheckIn.setH5RegisterCountA(response.getH5RegisterCountA());
                continue;
            }
            if("20".equals(col)){
                tempCheckIn.setH5RegisterCountB(response.getH5RegisterCountB());
                continue;
            }
            if("21".equals(col)){
                tempCheckIn.setLoginCount(response.getLoginCount());
                continue;
            }
            if("22".equals(col)){
                tempCheckIn.setAppRegisterCountA(response.getAppRegisterCountA());
                continue;
            }
            if("23".equals(col)){
                tempCheckIn.setAppRegisterCountB(response.getAppRegisterCountB());
                continue;
            }
            if("24".equals(col)){
                tempCheckIn.setUvPhone(response.getUvPhone());
                continue;
            }
            if("25".equals(col)){
                tempCheckIn.setUvApi(response.getUvApi());
                continue;
            }
            if("26".equals(col)){
                tempCheckIn.setApiApplyCount(response.getApiApplyCount());
                continue;
            }
            if("27".equals(col)){
                tempCheckIn.setApiLendCount(response.getApiLendCount());
                continue;
            }
            if("28".equals(col)){
                tempCheckIn.setApiLendTotalAmount(response.getApiLendTotalAmount());
            }
        }

        try {
            BeanUtilsBean2.getInstance().copyProperties(response, tempCheckIn);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }

    }


    private void klOperation(StatCollaborateCheckIn response, Integer ratio) {
        response.setH5CheckInCount(getKlData(response.getH5CheckInCount(), ratio));
        response.setH5ViewPageCount(getKlData(response.getH5ViewPageCount(), ratio));
        response.setH5RegisterCountA(getKlData(response.getH5RegisterCountA(), ratio));
        response.setH5RegisterCountB(getKlData(response.getH5RegisterCountB(), ratio));
        response.setLoginCount(getKlData(response.getLoginCount(), ratio));
        response.setAppRegisterCountA(getKlData(response.getAppRegisterCountA(), ratio));
        response.setAppRegisterCountB(getKlData(response.getAppRegisterCountB(), ratio));
        response.setUvPhone(getKlData(response.getUvPhone(), ratio));
        response.setUvApi(getKlData(response.getUvApi(), ratio));
        response.setApiApplyCount(getKlData(response.getApiApplyCount(), ratio));
        response.setApiLendCount(getKlData(response.getApiLendCount(), ratio));
        response.setApiLendTotalAmount(getKlData(response.getApiLendCount(), ratio));

    }

    private Integer getKlData(Integer source, Integer ratio){
        if(null != source && null != ratio){
            return Math.round((float)source*ratio/100);
        }
        return source;
    }

    @Override
    protected JpaRepository<StatCollaborateCheckIn, Long> getRepository() {
        return statCollaborateCheckInLoginRepository;
    }
}
